package com.dingup.paike.schedule;


import com.alibaba.fastjson.JSON;
import com.dingup.api.model.classInfo.ClassInfo;
import com.dingup.paike.adapter.pk.PkLessonInfoAdapter;
import com.dingup.paike.adapter.pk.PkLessonUserAdapter;
import com.dingup.paike.dao.PkLessonInfoMapper;
import com.dingup.paike.dao.PkLessonStudentSignMapper;
import com.dingup.paike.dao.PkLessonUserMapper;
import com.dingup.paike.enums.MessageTypeEnum;
import com.dingup.paike.enums.PkLessonUserTypeEnum;
import com.dingup.paike.feign.client.classInfo.ClassInfoFeignClient;
import com.dingup.paike.feign.client.user.UserFeignClient;
import com.dingup.paike.model.pk.PkLessonInfo;
import com.dingup.paike.model.pk.PkLessonUser;
import com.dingup.paike.service.message.DingTalkMsgService;
import com.dingup.paike.service.message.MessageService;
import com.dingup.paike.service.message.WxMsgService;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by wancheng on 2018/8/31.
 */

@Component
public class MessageSchedule {

    private static Logger logger = LoggerFactory.getLogger(MessageSchedule.class);

    @Autowired
    MessageService messageService;
    @Autowired
    DingTalkMsgService dingTalkMsgService;
    @Autowired
    WxMsgService wxMsgService;
    @Autowired
    UserFeignClient userFeignClient;
    @Autowired
    PkLessonInfoMapper pkLessonInfoMapper;
    @Autowired
    PkLessonUserMapper pkLessonUserMapper;
    @Autowired
    ClassInfoFeignClient classInfoFeignClient;
    @Autowired
    PkLessonStudentSignMapper studentSignMapper;


    /**
     * 执行每天晚上8点定时任务
     * 给老师 学生 班主任 发送第二天的上课提醒
     */
    @Scheduled(cron = "0 0 20 * * ?")
    public void sendRemindOfClassForUser() {
        List<PkLessonUserAdapter> pkLessonInfos = messageService.getPkLessonUserInfoForTomorrow();
        Map<PkLessonUserTypeEnum, List<PkLessonUserAdapter>> pkLessonUserMap = pkLessonInfos.stream().collect(Collectors.groupingBy(PkLessonUserAdapter::getType));
        //老师
        List<PkLessonUserAdapter> teachers = pkLessonUserMap.get(PkLessonUserTypeEnum.TEACHER);
        if (!CollectionUtils.isEmpty(teachers)) {
            Map<String, List<PkLessonUserAdapter>> teacherMap = teachers.stream().collect(Collectors.groupingBy(PkLessonUserAdapter::getUserId));
            teacherMap.entrySet().forEach(
                    e -> {
                        try {
                            String teacherName = e.getValue().get(0).getUserName();
                            dingTalkMsgService.sendMsgBeforeClassAtYesterdayForTeacher(e.getKey(), teacherName, e.getValue().stream().map(PkLessonUserAdapter::getPkLessonId).collect(Collectors.toList()));
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    });
        }
        logger.info("执行8点任务:发送第二天上课提醒,角色:老师,param={}", JSON.toJSONString(teachers));
        //班主任
        List<PkLessonUserAdapter> masters = pkLessonUserMap.get(PkLessonUserTypeEnum.MASTER);
        if (!CollectionUtils.isEmpty(masters)) {
            Map<String, List<PkLessonUserAdapter>> masterMap = masters.stream().collect(Collectors.groupingBy(PkLessonUserAdapter::getUserId));
            masterMap.entrySet().forEach(
                    e -> {
                        try {
                            String teacherName = e.getValue().get(0).getUserName();
                            dingTalkMsgService.sendMsgBeforeClassAtYesterdayForMaster(e.getKey(), teacherName, e.getValue().stream().map(PkLessonUserAdapter::getPkLessonId).collect(Collectors.toList()));
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    });
        }
        logger.info("执行8点任务:发送第二天上课提醒,角色:班主任,param={}", JSON.toJSONString(masters));
        //学生
        List<PkLessonUserAdapter> students = pkLessonUserMap.get(PkLessonUserTypeEnum.STUDENT);
        if (!CollectionUtils.isEmpty(students)) {
            Map<String, List<PkLessonUserAdapter>> studentMap = students.stream().collect(Collectors.groupingBy(PkLessonUserAdapter::getUserId));
            studentMap.entrySet().forEach(
                    e -> {
                        try {
                            String studentName = e.getValue().get(0).getUserName();
                            Date beginTime = e.getValue().get(0).getBeginTime();
                            String openId = userFeignClient.getWxOpenId(e.getKey());
                            List<Integer> pkLessonIds = e.getValue().stream().map(PkLessonUserAdapter::getPkLessonId).collect(Collectors.toList());
                            wxMsgService.sendMsgOfNextDayLessonInfo(openId, beginTime, studentName, e.getKey(), pkLessonIds);
                            List<String> parentOpenId = userFeignClient.getParentWxOpenId(e.getKey());
                            if (!CollectionUtils.isEmpty(parentOpenId)) {
                                parentOpenId.forEach(
                                        p -> wxMsgService.sendMsgOfNextDayLessonInfoForParents(p, beginTime, studentName, e.getKey(), pkLessonIds)
                                );
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    });

        }
        logger.info("执行8点任务:发送第二天上课提醒,角色:学生,param={}", JSON.toJSONString(students));

    }

    /**
     * 上课前1个小时提醒
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void sendRemindMsgBeforeLesson() {
        Date before = DateUtils.addHours(DateUtils.truncate(new Date(), Calendar.MINUTE), 1);
        Date after = DateUtils.addMinutes(before, 5);
        List<PkLessonInfoAdapter> pkLessonInfos = pkLessonInfoMapper.getPkLessonBetween(before, after, null);
        logger.info("执行5分钟任务:上课前1h提醒,param={}", JSON.toJSONString(pkLessonInfos));
        sendMsg(pkLessonInfos, MessageTypeEnum.MESSAGE_CLASS_BEFORE_ONE_HOUR);
    }

    public void sendMsg(List<PkLessonInfoAdapter> pkLessonInfos, MessageTypeEnum type) {
        Map<Integer, PkLessonInfoAdapter> lessonMap = pkLessonInfos.stream().collect(Collectors.toMap(PkLessonInfoAdapter::getId, l -> l));
        List<PkLessonUser> lessonUsers = new ArrayList<>();
        pkLessonInfos.forEach(
                p -> lessonUsers.addAll(p.getUsers())
        );
        Map<PkLessonUserTypeEnum, List<PkLessonUser>> userMap = lessonUsers.stream().collect(Collectors.groupingBy(PkLessonUser::getType));
        //老师
        List<PkLessonUser> teachers = userMap.get(PkLessonUserTypeEnum.TEACHER);
        if (!CollectionUtils.isEmpty(teachers)) {
            teachers.stream().forEach(
                    t -> {
                        PkLessonInfoAdapter p = lessonMap.get(t.getPkLessonId());
                        ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(p.getClassId());
                        dingTalkMsgService.sendMsgBeforeTenMinute(t, classInfo.getClassName(), type, p);

                    }
            );
        }
        //班主任
        List<PkLessonUser> masters = userMap.get(PkLessonUserTypeEnum.MASTER);
        if (!CollectionUtils.isEmpty(masters)) {
            masters.stream().forEach(
                    m -> {
                        PkLessonInfoAdapter pk = lessonMap.get(m.getPkLessonId());
                        ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(pk.getClassId());
                        dingTalkMsgService.sendMsgBeforeTenMinute(m, classInfo.getClassName(), type, pk);
                    }
            );
        }
        //学生
        List<PkLessonUser> students = userMap.get(PkLessonUserTypeEnum.STUDENT);
        if (!CollectionUtils.isEmpty(students)) {
            students.forEach(
                    s -> {
                        Date beginTime = lessonMap.get(s.getPkLessonId()).getBeginTime();
                        String lessonName = lessonMap.get(s.getPkLessonId()).getLessonName();
                        Integer lessonId = s.getPkLessonId();
                        String openId = userFeignClient.getWxOpenId(s.getUserId());
                        wxMsgService.sendMsgAt20MinBeforeClass(lessonName, lessonId, openId, beginTime, s.getUserId(), s.getUserName(), type);
                    }
            );
        }

    }

    /**
     * classIn上课前20分钟
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void sendRemindMsgBeforeLessonForClassIn() {
        Date before = DateUtils.addMinutes(DateUtils.truncate(new Date(), Calendar.MINUTE), 20);
        Date after = DateUtils.addMinutes(before, 5);
        List<PkLessonInfoAdapter> pkLessonInfos = pkLessonInfoMapper.getPkLessonBetween(before, after, true);
        sendMsg(pkLessonInfos, MessageTypeEnum.MESSAGE_CLASS_CLASS_IN);
        logger.info("执行5分钟任务:上课前20min提醒,param={}", JSON.toJSONString(pkLessonInfos));
    }

    /**
     * 发送班主任的签到表
     */
    @Scheduled(cron = "0 0 7 * * ?")
    public void sendStudentSignIn() {
        Date before = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
        Date after = DateUtils.addDays(before, 1);
        List<PkLessonInfoAdapter> pkLessonInfos = pkLessonInfoMapper.getPkLessonBetween(before, after, null);
        Map<Integer, PkLessonInfoAdapter> lessonMap = pkLessonInfos.stream().collect(Collectors.toMap(PkLessonInfoAdapter::getId, l -> l));
        List<PkLessonUser> lessonUsers = new ArrayList<>();
        pkLessonInfos.forEach(
                p -> lessonUsers.addAll(p.getUsers())
        );
        Map<PkLessonUserTypeEnum, List<PkLessonUser>> userMap = lessonUsers.stream().collect(Collectors.groupingBy(PkLessonUser::getType));
        //班主任发送签到表
        List<PkLessonUser> masters = userMap.get(PkLessonUserTypeEnum.MASTER);
        //班主任可能负责多个班级,多个课节,对班主任进行分组
        Map<String, List<PkLessonUser>> masterGroupMap = masters.stream().collect(Collectors.groupingBy(PkLessonUser::getUserId));
        if (!CollectionUtils.isEmpty(masterGroupMap)) {
            masterGroupMap.entrySet().forEach(
                    e -> {
                        PkLessonUser master = e.getValue().get(0);
                        List<Integer> pkLessonIds = e.getValue().stream().map(PkLessonUser::getPkLessonId).collect(Collectors.toList());
                        dingTalkMsgService.sendMsgOfSignInForMaster(master, pkLessonIds);
                    }
            );
        }
        logger.info("执行任务:签到表,param={}", JSON.toJSONString(masterGroupMap));
    }



    /**
     * 发送课时确认
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void sendLessonConfirm() {
        Date currentDate = new Date();
        Date before = DateUtils.truncate(currentDate, Calendar.MINUTE);
        Date after = DateUtils.addMinutes(before, 5);
        List<PkLessonInfo> pkLessonInfos = pkLessonInfoMapper.getPkLessonEndTimeBetween(before, after);
        if (!CollectionUtils.isEmpty(pkLessonInfos)) {
            pkLessonInfos.forEach(
                    l -> {
                        PkLessonUser master = pkLessonUserMapper.getByPkLessonIdAndType(l.getId(), null, PkLessonUserTypeEnum.MASTER);
                        if (master != null) {
                            dingTalkMsgService.sendMsgOfConfirmClassHourForMaster(master, l);
                        }
                    }
            );
        }
    }

    /**
     * 发送反馈提醒
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void sendFeedbackMsg() {
        Date currentDate = new Date();
        Date before = DateUtils.truncate(currentDate, Calendar.MINUTE);
        Date after = DateUtils.addMinutes(before, 5);
        List<PkLessonInfo> pkLessonInfos = pkLessonInfoMapper.getPkLessonBeginTimeBetween(before, after);
        if (!CollectionUtils.isEmpty(pkLessonInfos)) {
            pkLessonInfos.forEach(
                    l -> {
                        PkLessonUser master = pkLessonUserMapper.getByPkLessonIdAndType(l.getId(), null, PkLessonUserTypeEnum.MASTER);
                        PkLessonUser teacher = pkLessonUserMapper.getByPkLessonIdAndType(l.getId(), null, PkLessonUserTypeEnum.TEACHER);
                        if (master != null) {
                            dingTalkMsgService.sendMsgAfterClassTextForMaster(master, l);
                        }
                        if (master != teacher) {
                            dingTalkMsgService.sendMsgAfterClassForTeacher(teacher, l);
                        }
                    }
            );
        }
    }
}
